package pl.edu.agh.mikro.WifiSpybot;


import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import pl.edu.agh.mikro.WifiSpybot.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import pl.edu.agh.mikro.WifiSpybot.MjpegInputStream;
import pl.edu.agh.mikro.WifiSpybot.MjpegView;
//import android.webkit.WebView;



@SuppressWarnings("unused")
public class WifiSpybotActivity extends Activity implements SensorEventListener {

    private MjpegView mv;
    //private WebView webview;
    private String currentIP = "";
    private String currentServerIP = "";
    private String currentPort = "8080";
    private String currentServerPort = "8081";
    private boolean enabled = false;
    private int currentSpeed = 0;
    private int speed = 0;
    
    private static final char BACKWARD = 'a';
    private static final char STP = 'b';
    private static final char FORWARD = 'c';
    private static final char RIGHT = 'd';
    private static final char LEFT = 'e';
    private static final char SPEED1 = '1';
    private static final char SPEED2 = '2';
    private static final char SPEED3 = '3';
    
    public static final int MOTION_UP = 0;
    public static final int MOTION_DOWN = 1;
    public static final int MOTION_RIGHT = 2;
    public static final int MOTION_LEFT = 3;
    
    
    public static final int STOP = 0;
    public static final int UP = 1;
    public static final int DOWN = 2;
    public static final int R_STOP = 3;
    public static final int R_UP = 4;
    public static final int R_DOWN = 5;
    public static final int L_STOP = 6;
    public static final int L_UP = 7;
    public static final int L_DOWN = 8;
    
    int currentState = STOP;
    
    private static final int MENU_QUIT = 1;
    private static final int CHANGE_IP = 2;
    private static final int CHANGE_PORT = 3;
    private static final int CHANGE_SERVER_IP = 4;
    private static final int CHANGE_SERVER_PORT = 5;
    
    private SensorManager mSensorManager;
    private Sensor mOrientation;
    private final float NOISE = (float) 20.0;
    private final float NOISE_SPEED = (float) 30.0;
    private final float NOISE_Z = (float) 15.0;
    
    private Socket socket = null;
	private DataOutputStream dataOutputStream = null;

    /* Creates the menu items */
    public boolean onCreateOptionsMenu(Menu menu) {    
    menu.add(0, MENU_QUIT, 0, "Quit");
    menu.add(0, CHANGE_IP, 0, "Enable");
    menu.add(0, CHANGE_PORT, 0, "Disable");
    menu.add(0, CHANGE_SERVER_IP, 0, "Change server IP");
    menu.add(0, CHANGE_SERVER_PORT, 0, "Change server Port");
    return true;
    }

    /* Handles item selections */
    public boolean onOptionsItemSelected(MenuItem item) {    
        switch (item.getItemId()) {
            case MENU_QUIT:
                finish();
                return true;
            case CHANGE_IP:
            	enabled = true;
                //changeIP();
                return true;
            case CHANGE_PORT:
                enabled = false;
                return true;
            case CHANGE_SERVER_IP:
                changeServerIP();
                return true;
            case CHANGE_SERVER_PORT:
                changeServerPort();
                return true;
            }    
        return false;
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        
 
        
        //String URL = "http://192.168.1.2:8080/videofeed";
        
         mv = new MjpegView(this);
         setContentView(mv); 
         Toast.makeText(getApplicationContext(), "ON CREATE", Toast.LENGTH_SHORT).show();
        AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("WifiSpybot");
        alert.setMessage("Enter IP:");

        final EditText input = new EditText(this);
        alert.setView(input);

        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          final String IP = input.getText().toString();
          currentIP = IP;
          currentServerIP = IP;
          mv.setSource(MjpegInputStream.read("http://"+IP+":8080/videofeed"));
          mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);
          mv.showFps(false);
          }
        });
        alert.show();
        
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        mSensorManager.registerListener(this, mOrientation , SensorManager.SENSOR_DELAY_NORMAL);
        
       /* WebView webview = new WebView(this);
        setContentView(webview);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.loadUrl("http://192.168.1.2:8080/jsfs.html");*/

    }
    
    public void onResume() {
    	 super.onResume();
    	 Toast.makeText(getApplicationContext(), "ON RESUME", Toast.LENGTH_SHORT).show();
    	 mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void onPause() {
        super.onPause();
        Toast.makeText(getApplicationContext(), "ON PAUSE", Toast.LENGTH_SHORT).show();
        mSensorManager.unregisterListener(this);
        mv.stopPlayback();
        
        try {
			if (dataOutputStream != null) dataOutputStream.close();
			dataOutputStream = null;
			if(socket != null) socket.close();
			socket = null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
    
    public void changeIP() {
    	//mv.stopPlayback();
    	AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("WifiSpybot");
        alert.setMessage("Enter camera IP:");

        final EditText input = new EditText(this);
        alert.setView(input);

        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          final String IP = input.getText().toString();
          currentIP = IP;
          mv.setSource(MjpegInputStream.read("http://"+IP+":"+currentPort+"/videofeed"));
          mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);
          mv.showFps(false);
          }
        });
        alert.show();
    	
    }
    
    public void changeServerIP() {
    	AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("WifiSpybot");
        alert.setMessage("Enter server IP:");

        final EditText input = new EditText(this);
        alert.setView(input);

        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          final String IP = input.getText().toString();
          currentServerIP = IP;
          try {
			if (dataOutputStream != null) dataOutputStream.close();
			dataOutputStream = null;
			if(socket != null) socket.close();
			socket = null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        }
        });
        alert.show();
    	
    }
    
    public void changePort() {
    	//mv.stopPlayback();
    	AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("WifiSpybot");
        alert.setMessage("Enter cam port number:");

        final EditText input = new EditText(this);
        alert.setView(input);

        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          final String PORT = input.getText().toString();
          currentPort = PORT;
          mv.setSource(MjpegInputStream.read("http://"+currentIP+":"+PORT+"/videofeed"));
          mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);
          mv.showFps(false);
          }
        });
        alert.show();
    }
    
    public void changeServerPort() {
    	AlertDialog.Builder alert = new AlertDialog.Builder(this);

        alert.setTitle("WifiSpybot");
        alert.setMessage("Enter server port number:");

        final EditText input = new EditText(this);
        alert.setView(input);

        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
          final String PORT = input.getText().toString();
          currentServerPort = PORT;
          try {
  			if (dataOutputStream != null) dataOutputStream.close();
  			dataOutputStream = null;
  			if(socket != null) socket.close();
  			socket = null;
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
          }
        });
        alert.show();
    }
    
    public void sendCommand(char cmd) {
    	if(enabled) {
    	try {
			if(socket == null) socket = new Socket(currentServerIP, Integer.parseInt(currentServerPort));
			if(dataOutputStream == null) dataOutputStream = new DataOutputStream(socket.getOutputStream());
			dataOutputStream.writeByte((int)cmd);
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	}
    }

    @Override
    public void onAccuracyChanged(Sensor arg0, int arg1) {
    	// TODO Auto-generated method stub

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
    	float x = event.values[0];
    	float y = event.values[1];
    	float z = event.values[2];

    	
    	
    	if ((Math.abs(y) > NOISE) && (Math.abs(y) <= NOISE_SPEED)) {
    		speed = 2;
    	}
    	else if (Math.abs(y) > NOISE_SPEED) {
    		speed = 3;
    	}
    	
    	
    	if ((Math.abs(y) > NOISE) && (Math.abs(z) <= NOISE_Z)) {

    		if (y>0) processMotion(MOTION_UP);
    		else processMotion(MOTION_DOWN);


    	} else if ((Math.abs(y) <= NOISE) && (Math.abs(z) > NOISE_Z)) {	
    		if (z>0) processMotion(MOTION_LEFT);
    		else processMotion(MOTION_RIGHT);


    	} else if ((Math.abs(y) > NOISE) && (Math.abs(z) > NOISE_Z)) {
    		if(currentState == R_STOP || currentState == L_STOP) {
    			if (y>0) processMotion(MOTION_UP);
    			else processMotion(MOTION_DOWN);
    		}
    		else {
    			if (y>0) processMotion(MOTION_UP);
    			else processMotion(MOTION_DOWN);
    			
    			if (z>0) processMotion(MOTION_LEFT);
    			else processMotion(MOTION_RIGHT);
    		}
    	} else if(currentState != STOP) {
    		currentState = STOP;
    		sendCommand(STP);
    	}
    }



    public void processMotion(int motion) {
		if (motion == MOTION_UP) {

			if(currentState == UP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
						sendCommand(FORWARD);
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
						sendCommand(FORWARD);
					}
				}		
			}
			
			if(currentState == L_UP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
						sendCommand(FORWARD);
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
						sendCommand(FORWARD);
					}
				}
				
			}
			if(currentState == R_UP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
						sendCommand(FORWARD);
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
						sendCommand(FORWARD);
					}
				}
				
				
			}

			if(currentState == STOP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
					}
				}
				sendCommand(FORWARD);
				currentState = UP;

			}
			if(currentState == DOWN) {
				sendCommand(STP);
				currentState = STOP;

			}
			if(currentState == R_STOP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
					}
				}
				sendCommand(FORWARD);
				currentState = R_UP;

			}
			if(currentState == R_DOWN) {
				sendCommand(STP);
				currentState = STOP;

			}
			if(currentState == L_STOP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
					}
				}
				sendCommand(FORWARD);
				currentState = L_UP;

			}
			if(currentState == L_DOWN) {
				sendCommand(STP);
				currentState = STOP;

			}

		}
		else if (motion == MOTION_DOWN) {
			
			if(currentState == DOWN) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
						sendCommand(BACKWARD);
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
						sendCommand(BACKWARD);
					}
				}
						
			}
			
			if(currentState == L_DOWN) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
						sendCommand(BACKWARD);
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
						sendCommand(BACKWARD);
					}
				}
				
				
			}
			if(currentState == R_DOWN) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
						sendCommand(BACKWARD);
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
						sendCommand(BACKWARD);
					}
				}
				
				
			}
			
			if(currentState == STOP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
					}
				}
				sendCommand(BACKWARD);
				currentState = DOWN;
				
			}
			if(currentState == UP) {
				sendCommand(STP);
				currentState = STOP;
							
			}
			if(currentState == R_STOP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
					}
				}
				sendCommand(BACKWARD);
				currentState = R_DOWN;
				
			}
			if(currentState == R_UP) {
				sendCommand(STP);
				currentState = STOP;
				
			}
			if(currentState == L_STOP) {
				if(currentSpeed != speed) {
					if(speed == 2) {
						sendCommand(SPEED2);
						currentSpeed = 2;
					}
					else {
						sendCommand(SPEED3);
						currentSpeed = 3;
					}
				}
				sendCommand(BACKWARD);
				currentState = L_DOWN;
				
			}
			if(currentState == L_UP) {
				sendCommand(STP);
				currentState = STOP;
				
			}
			
		}
		else if (motion == MOTION_RIGHT) {
			
			if(currentState == STOP) {
				sendCommand(RIGHT);
				currentState = R_STOP;
				
			}
			if(currentState == UP) {
				sendCommand(RIGHT);
				currentState = R_UP;
							
			}
			if(currentState == DOWN) {
				sendCommand(RIGHT);
				currentState = R_DOWN;
				
			}
			if(currentState == L_STOP) {
				sendCommand(STP);
				currentState = STOP;
				
			}
			if(currentState == L_UP) {
				sendCommand(RIGHT);
				currentState = R_UP;
				
			}
			if(currentState == L_DOWN) {
				sendCommand(RIGHT);
				currentState = R_DOWN;
				
			}
			
		}
		else if (motion == MOTION_LEFT) {
			
			if(currentState == STOP) {
				sendCommand(LEFT);
				currentState = L_STOP;
				
			}
			if(currentState == UP) {
				sendCommand(LEFT);
				currentState = L_UP;
							
			}
			if(currentState == DOWN) {
				sendCommand(LEFT);
				currentState = L_DOWN;
				
			}
			if(currentState == R_STOP) {
				sendCommand(STP);
				currentState = STOP;
				
			}
			if(currentState == R_UP) {
				sendCommand(LEFT);
				currentState = L_UP;
				
			}
			if(currentState == R_DOWN) {
				sendCommand(LEFT);
				currentState = L_DOWN;
				
			}
			
		}
	}
}
